package yunjiao.javatutorials.designpatterns.combinator;

/**
 * 表达式接口和实现
 *
 * @author yangyunjiao
 */
public interface Expr {
    int evaluate();

    static class NumberExpr implements Expr {
        private final int value;
        public NumberExpr(int value) { this.value = value; }
        public int evaluate() { return value; }
        public String toString() { return String.valueOf(value); }
    }

    static class AddExpr implements Expr {
        private final Expr left, right;
        public AddExpr(Expr left, Expr right) { this.left = left; this.right = right; }
        public int evaluate() { return left.evaluate() + right.evaluate(); }
        public String toString() { return "(" + left + " + " + right + ")"; }
    }

    static class SubtractExpr implements Expr {
        private final Expr left, right;
        public SubtractExpr(Expr left, Expr right) { this.left = left; this.right = right; }
        public int evaluate() { return left.evaluate() - right.evaluate(); }
        public String toString() { return "(" + left + " - " + right + ")"; }
    }

    static class MultiplyExpr implements Expr {
        private final Expr left, right;
        public MultiplyExpr(Expr left, Expr right) { this.left = left; this.right = right; }
        public int evaluate() { return left.evaluate() * right.evaluate(); }
        public String toString() { return "(" + left + " * " + right + ")"; }
    }

    static class DivideExpr implements Expr {
        private final Expr left, right;
        public DivideExpr(Expr left, Expr right) { this.left = left; this.right = right; }
        public int evaluate() { return left.evaluate() / right.evaluate(); }
        public String toString() { return "(" + left + " / " + right + ")"; }
    }
}
